﻿/*----------------------------------------------------------------
        // Copyright (C) Rookey
        // 版权所有
        // 开发者：Rookey
        // Email：rookey@yeah.net
        // 
//----------------------------------------------------------------*/

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using Rookey.Frame.Common;
using System.Web;
using Rookey.Frame.Operate.Base;
using Rookey.Frame.Base;
using Rookey.Frame.Controllers.Attr;
using Rookey.Frame.Operate.Base.TempModel;
using Rookey.Frame.Model.Sys;
using Rookey.Frame.Operate.Base.Extension;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Http;
using System.Net.Http;
using Rookey.Frame.Controllers.Other;
using System.Web.Security;
using Rookey.Frame.Base.Set;
using Rookey.Frame.Model.OrgM;
using Rookey.Frame.Model.Log;
using Rookey.Frame.Operate.Base.OperateHandle;

namespace Rookey.Frame.Controllers
{
    /// <summary>
    /// 用户控制器（异步）
    /// </summary>
    public class UserAsyncController : AsyncBaseController
    {
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="userpwd">密码</param>
        /// <param name="valcode">验证码</param>
        /// <returns></returns>
        [Login]
        [Anonymous]
        public Task<ActionResult> UserLoginAsync(string username, string userpwd, string valcode)
        {
            return Task.Factory.StartNew(() =>
            {
                return new UserController(Request, Response, Session, TempData).UserLogin(username, userpwd, valcode);
            }).ContinueWith<ActionResult>(task =>
            {
                return task.Result;
            });
        }

        /// <summary>
        /// 获取数据权限组织树
        /// </summary>
        /// <returns></returns>
        public Task<ActionResult> GetDataPermissionOrgTreeAsync()
        {
            return Task.Factory.StartNew(() =>
            {
                return new UserController(Request).GetDataPermissionOrgTree();
            }).ContinueWith<ActionResult>(task =>
            {
                return task.Result;
            });
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        public Task<ActionResult> ChangePwdAsync()
        {
            return Task.Factory.StartNew(() =>
            {
                return new UserController(Request).ChangePwd();
            }).ContinueWith<ActionResult>(task =>
            {
                return task.Result;
            });
        }
    }

    /// <summary>
    /// 用户控制器
    /// </summary>
    public class UserController : BaseController
    {
        #region 构造函数

        private HttpSessionStateBase _Session = null; //Session
        private HttpRequestBase _Request = null; //请求对象
        private HttpResponseBase _Response = null; //响应对象
        private TempDataDictionary _TempData = null; //临时字典对象

        /// <summary>
        /// 无参构造函数
        /// </summary>
        public UserController()
        {
            _Request = Request;
            _Session = Session;
            _Response = Response;
            _TempData = TempData;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="request">请求对象</param>
        public UserController(HttpRequestBase request)
            : base(request)
        {
            _Request = request;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="request">请求对象</param>
        /// <param name="response">返回请求</param>
        /// <param name="session">session</param>
        public UserController(HttpRequestBase request, HttpResponseBase response, HttpSessionStateBase session, TempDataDictionary tempData)
            : base(request)
        {
            _Request = request;
            _Session = session;
            _Response = response;
            _TempData = tempData;
        }

        #endregion

        #region 公共方法

        private const string LOGINERROR = "LoginError";

        /// <summary>
        /// 登录页面
        /// </summary>
        /// <returns></returns>
        [Anonymous]
        public ActionResult Login()
        {
            if (!ToolOperate.IsNeedInit()) //不需要初始化时
            {
                if (WebConfigHelper.GetAppSettingValue("NeedRepairTable") == "true") //需要修复数据表
                {
                    string tables = WebConfigHelper.GetAppSettingValue("RepairTables"); //要修复的数据表
                    List<string> token = new List<string>();
                    if (!string.IsNullOrEmpty(tables))
                    {
                        token = tables.Split(",".ToCharArray()).ToList();
                    }
                    if (token.Count > 0)
                    {
                        ToolOperate.RepairTables(token);
                    }
                }
            }
            else //需要初始化
            {
                return RedirectToAction("Init", "Page");
            }
            ViewBag.IsShowValidateCode = (Session[LOGINERROR].ObjToInt() >= 2).ToString().ToLower();
            return View();
        }

        /// <summary>
        /// 弹出登录框
        /// </summary>
        /// <returns></returns>
        [Anonymous]
        public ActionResult DialogLogin()
        {
            ViewBag.IsShowValidateCode = (Convert.ToInt32(Session[LOGINERROR]) >= 2).ToString().ToLower();
            return View();
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="userpwd">密码</param>
        /// <param name="valcode">验证码</param>
        /// <returns></returns>
        [Login]
        [Anonymous]
        public ActionResult UserLogin(string username, string userpwd, string valcode)
        {
            if (_Request == null) _Request = Request;
            if (_Response == null) _Response = Response;
            if (_Session == null) _Session = Session;
            string errMsg = string.Empty;
            ViewBag.IsShowValidateCode = "false";
            bool isNoCode = _Request["isNoCode"].ObjToBool(); //是否不需要验证码
            if (!isNoCode && _Session[LOGINERROR].ObjToInt() >= 2)
            {
                bool validatecode = false;
                if (_TempData.ContainsKey(SecurityController.VALIDATECODE))
                {
                    string code = _TempData[SecurityController.VALIDATECODE].ToString();
                    validatecode = valcode.ToLower() == code.ToLower();
                }
                if (!validatecode)
                {
                    return Json(new LoginReturnResult() { Success = false, Message = "验证码错误！", IsShowCode = true });
                }
            }
            //获取用户信息
            string tempUserName = GetUserName(username);
            UserInfo userInfo = UserOperate.GetUserInfo(tempUserName, userpwd, out errMsg);
            if (!string.IsNullOrEmpty(errMsg)) //账号密码方式登录失败
            {
                //尝试AD域账号登录
                userInfo = UserOperate.GetUserInfoByAdDomain(tempUserName, userpwd);
                if (userInfo == null) //ad域登录失败后返回
                {
                    var isShowCode = false;
                    _Session[LOGINERROR] = _Session[LOGINERROR] == null ? 0 : _Session[LOGINERROR].ObjToInt() + 1;
                    if (!isNoCode && _Session[LOGINERROR].ObjToInt() >= 2)
                        isShowCode = true;
                    return Json(new LoginReturnResult() { Success = false, Message = errMsg, IsShowCode = isShowCode });
                }
            }
            CacheUserData(userInfo); //缓存cookie
            //执行登录成功后的操作
            CommonOperate.ExecuteUserOperateHandleMethod("AfterLoginSuccess", new object[] { _Session, _Request, _Response, username, userpwd, UserInfo.ACCOUNT_EXPIRATION_TIME });

            return Json(new LoginReturnResult() { Success = true, Message = string.Empty, Url = HttpUtility.UrlEncode(string.Empty) });
        }

        /// <summary>
        /// 获取用户名
        /// </summary>
        /// <param name="username">用户名或工号或邮箱或手机号</param>
        /// <returns></returns>
        private string GetUserName(string username)
        {
            string tempUserName = username.Trim();
            string errMsg = string.Empty;
            if (GlobalSet.IsAllowOtherConfigRuleLogin) //允许其他方式登录
            {
                //先检测默认登录规则账号是否存在
                bool rs = UserOperate.UserIsValid(tempUserName, out errMsg);
                if (rs)
                    return tempUserName;
                //默认登录规则账号不存在时检测其他方式
                OrgM_Emp emp = null;
                switch (GlobalSet.EmpUserNameConfigRule)
                {
                    case UserNameAndEmpConfigRule.EmpCode:
                        {
                            emp = OrgMOperate.GetEmpByMobile(tempUserName); //根据手机号获取员工
                            if (emp == null)
                            {
                                emp = OrgMOperate.GetEmpByEmail(tempUserName); //根据邮箱获取员工
                                if (emp == null)
                                    emp = OrgMOperate.GetEmpByEmailPrex(tempUserName); //根据邮箱前缀获取员工
                            }
                        }
                        break;
                    case UserNameAndEmpConfigRule.Mobile:
                        {
                            emp = OrgMOperate.GetEmpByCode(tempUserName); //根据工号获取员工
                            if (emp == null)
                            {
                                emp = OrgMOperate.GetEmpByEmail(tempUserName); //根据邮箱获取员工
                                if (emp == null)
                                    emp = OrgMOperate.GetEmpByEmailPrex(tempUserName); //根据邮箱前缀获取员工
                            }
                        }
                        break;
                    case UserNameAndEmpConfigRule.Email:
                        {
                            emp = OrgMOperate.GetEmpByCode(tempUserName); //根据工号获取员工
                            if (emp == null)
                            {
                                emp = OrgMOperate.GetEmpByMobile(tempUserName); //根据手机号获取员工
                                if (emp == null)
                                    emp = OrgMOperate.GetEmpByEmailPrex(tempUserName); //根据邮箱前缀获取员工
                            }
                        }
                        break;
                    case UserNameAndEmpConfigRule.EmailPre:
                        {
                            emp = OrgMOperate.GetEmpByCode(tempUserName); //根据工号获取员工
                            if (emp == null)
                            {
                                emp = OrgMOperate.GetEmpByMobile(tempUserName); //根据手机号获取员工
                                if (emp == null)
                                    emp = OrgMOperate.GetEmpByEmail(tempUserName); //根据邮箱获取员工
                            }
                        }
                        break;
                }
                if (emp != null)
                    return OrgMOperate.GetUserNameByEmp(emp);
            }
            return tempUserName;
        }

        /// <summary>
        /// 切换用户
        /// </summary>
        /// <returns></returns>
        public ActionResult ChangeUser()
        {
            if (_Request == null) _Request = Request;
            if (_Response == null) _Response = Response;
            if (_Session == null) _Session = Session;
            SetRequest(_Request);
            UserInfo currUser = GetCurrentUser(_Request);
            if (currUser == null)
                return Json(new ReturnResult() { Success = false, Message = "非法操作" });
            string username = _Request["username"].ObjToStr();
            if (username == "admin")
                return Json(new ReturnResult() { Success = false, Message = "没有权限" });
            Guid userId = UserOperate.GetUserIdByUserName(username);
            UserInfo userInfo = UserOperate.GetUserInfo(userId);
            if (userInfo == null)
                return Json(new ReturnResult() { Success = false, Message = "用户不存在" });
            userInfo.ClientBrowserWidth = currUser.ClientBrowserWidth;
            userInfo.ClientBrowserHeight = currUser.ClientBrowserHeight;
            CacheUserData(userInfo); //缓存cookie
            return Json(new ReturnResult() { Success = true, Message = string.Empty });
        }

        /// <summary>
        /// 缓存用户Cookie数据
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <returns></returns>
        private void CacheUserData(UserInfo userInfo)
        {
            _Session[LOGINERROR] = null;
            //客户端浏览器参数
            int w = _Request["w"].ObjToInt();
            int h = _Request["h"].ObjToInt();
            if (w > 0)
                userInfo.ClientBrowserWidth = w;
            if (h > 0)
                userInfo.ClientBrowserHeight = h;
            //获取客户端IP
            userInfo.ClientIP = WebHelper.GetClientIP(_Request);
            //缓存用户扩展信息
            UserInfo.CacheUserExtendInfo(userInfo.UserName, userInfo.ExtendUserObject);
            //用户票据保存
            FormsPrincipal.Login(userInfo.UserName, userInfo, UserInfo.ACCOUNT_EXPIRATION_TIME, GetHttpContext(_Request));
            //登录成功写cookie，保存客户端用户名
            var userNameCookie = new HttpCookie("UserName", userInfo.UserName);
            userNameCookie.Expires = DateTime.Now.AddDays(365);
            _Response.Cookies.Add(userNameCookie);
        }

        /// <summary>
        /// 登出
        /// </summary>
        /// <returns></returns>
        public ActionResult Logout()
        {
            if (_Response == null) _Response = Response;
            if (_Session == null) _Session = Session;
            FormsPrincipal.Logout(_Response, _Session);
            return RedirectToAction("Login");
        }

        /// <summary>
        /// 获取数据权限组织树
        /// </summary>
        /// <returns></returns>
        public ActionResult GetDataPermissionOrgTree()
        {
            if (_Request == null) _Request = Request;
            SetRequest(_Request);
            bool isAsync = _Request["async"].ObjToInt() == 1; //是否异步
            Guid? tempId = _Request["id"].ObjToGuidNull();
            TreeNode tempNode = new TreeNode() { id = "-1", text = "全部", iconCls = "eu-icon-dept" };
            TreeNode currDeptNode = new TreeNode() { id = "0", text = "本部门", iconCls = "eu-icon-dept" };
            Expression<Func<Sys_Organization, bool>> expression = null;
            string q = _Request["q"].ObjToStr(); //查询字符
            if (!string.IsNullOrEmpty(q))
                expression = x => x.Name.Contains(q);
            TreeNode node = CommonOperate.GetTreeNode<Sys_Organization>(tempId, null, null, null, null, "eu-icon-dept", expression, null, null, isAsync, GetCurrentUser(_Request));
            if (isAsync)
            {
                node.state = "closed";
                if (node.children != null && node.children.Count() > 0)
                {
                    node.children.ForEach(x => { x.state = "closed"; });
                }
            }
            if (tempId == null || tempId == Guid.Empty)
            {
                List<TreeNode> list = new List<TreeNode> { tempNode, currDeptNode };
                if (node != null) list.Add(node);
                return Json(list.ToJson().Content);
            }
            else
            {
                return Json(node.children.ToJson().Content);
            }
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        public ActionResult ChangePwd()
        {
            if (_Request == null) _Request = Request;
            SetRequest(_Request);
            UserInfo currUser = GetCurrentUser(_Request);
            if (currUser == null)
            {
                return Json(new ReturnResult() { Success = false, Message = "您未登录系统或登录时间过长，请重新登录系统后再修改密码！" });
            }
            string errMsg = string.Empty;
            string oldPwd = _Request["oldPwd"].ObjToStr();
            string newPwd = _Request["newPwd"].ObjToStr();
            UserInfo tempUserInfo = UserOperate.GetUserInfo(currUser.UserName, oldPwd, out errMsg);
            if (tempUserInfo == null)
            {
                return Json(new ReturnResult() { Success = false, Message = "您当前登录密码输入不正确，请重新输入！" });
            }
            bool rs = UserOperate.ModifyPassword(currUser.UserId, newPwd, out errMsg);
            if (rs)
            {
                CommonOperate.ExecuteUserOperateHandleMethod("AfterChangePwd", new object[] { currUser.UserName, oldPwd, newPwd });
            }
            return Json(new ReturnResult() { Success = rs, Message = errMsg });
        }

        #region 短信邮箱验证
        /// <summary>
        /// 发送短信
        /// </summary>
        /// <returns></returns>
        public ActionResult SendSns()
        {
            string mobile = Request["m"].ObjToStr();
            if (string.IsNullOrEmpty(mobile))
                return Json(new { Success = false, Msg = "手机号不能为空" }, JsonRequestBehavior.AllowGet);
            string um = Request["um"].ObjToStr();
            string code = new Random().Next(100000, 999999).ToString();
            Sys_ValidationLog validlog = new Sys_ValidationLog();
            validlog.VerifyCode = code;
            validlog.UserName = um;
            validlog.VerifyAccount = mobile;
            validlog.Status = "未使用";
            validlog.Description = Request["des"].ObjToStr();
            validlog.CreateDate = DateTime.Now;
            validlog.CreateUserName = "admin";
            string errMsg = string.Empty;
            string clientIp = string.Empty;
            if (Request.ServerVariables["HTTP_VIA"] != null) //使用代理
            {
                clientIp = Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString(); // 返回真实的客户端IP 
            }
            else// 没有使用代理时获取客户端IP 
            {
                clientIp = Request.ServerVariables["REMOTE_ADDR"].ToString(); //当不能获取客户端IP时,将获取客户端代理IP. 
            }
            validlog.IPAddress = clientIp;
            if (mobile.Contains("@")) //邮箱验证
            {
                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add(mobile, mobile);
                string msg = SystemOperate.EmailSend("OA邮箱验证码", string.Format("验证码：{0}", code), dic, null, null, null, false);
                if (string.IsNullOrEmpty(msg))
                {
                    string md5Code = MySecurity.GetMd5Str(code).ToLower();
                    validlog.MD5 = md5Code;
                    validlog.VerifyMethod = "邮箱";
                    CommonOperate.OperateRecord<Sys_ValidationLog>(validlog, ModelRecordOperateType.Add, out errMsg, null, false); //添加发送日志
                    return Json(new { Success = true, Msg = "验证邮件已发送，请查收", M = mobile, Code = md5Code }, JsonRequestBehavior.AllowGet);
                }
                return Json(new { Success = false, Msg = "验证邮件发送失败，请重试" }, JsonRequestBehavior.AllowGet);
            }
            else //手机验证
            {
                string content = Server.UrlEncode(string.Format("您的OA验证码为：{0},验证码有效期为5分钟，请您尽快输入完成验证，切勿告知他人", code));
                string snsUrl = "http://10.10.10.172:8100/se-manager/smsApi/sendSms.do";
                string param = string.Format("key=1f2121f36f817bd18540e5fa7de06f59&sourceName=OA&telNum={0}&content={1}", mobile, content);
                byte[] bTemp = System.Text.Encoding.UTF8.GetBytes(param);
                DataMutual dm = new DataMutual(snsUrl);
                string msg = dm.Start(bTemp);
                if (msg == "{\"status\":100,\"message\":\"OK\"}")
                {
                    string md5Code = MySecurity.GetMd5Str(code).ToLower();
                    validlog.MD5 = md5Code;
                    validlog.VerifyMethod = "手机";
                    CommonOperate.OperateRecord<Sys_ValidationLog>(validlog, ModelRecordOperateType.Add, out errMsg, null, false); //添加发送日志
                    return Json(new { Success = true, Msg = "短信已发送，请查收", M = mobile, Code = md5Code }, JsonRequestBehavior.AllowGet);
                }
                return Json(new { Success = false, Msg = "短信发送失败，请重试" }, JsonRequestBehavior.AllowGet);
            }
        }

        /// <summary>
        /// 获取当前用户手机号和邮箱
        /// </summary>
        /// <returns></returns>
        public ActionResult GetCurrEmpMobile()
        {
            OrgM_Emp emp = null;
            Guid empId = Request["empId"].ObjToGuid();
            string um = Request["username"].ObjToStr();
            if (empId == Guid.Empty)
            {
                UserInfo currUser = GetCurrentUser(Request);
                if (currUser == null)
                    return Json(null, JsonRequestBehavior.AllowGet);
                if (currUser == null || !currUser.EmpId.HasValue || currUser.EmpId.Value == Guid.Empty)
                    return Json(null, JsonRequestBehavior.AllowGet);
                emp = OrgMOperate.GetEmp(currUser.EmpId.Value);
            }
            else
            {
                emp = OrgMOperate.GetEmp(empId);
            }
            if (string.IsNullOrEmpty(um))
                um = emp.Email.Split("@".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[0];
            if (emp == null || string.IsNullOrEmpty(emp.Mobile))
                return Json(null, JsonRequestBehavior.AllowGet);
            string mobile = emp.Mobile.ObjToStr().Trim();
            if (mobile.Contains("("))
                mobile = mobile.Split("(".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[0];
            return Json(new { M = mobile, Email = emp.Email.ObjToStr().Trim(), Um = um }, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 更新短信发送日志状态
        /// </summary>
        /// <returns></returns>
        public ActionResult UpdateValidLog()
        {
            string um = Request["um"].ObjToStr();
            string code = Request["code"].ObjToStr();
            string errMsg = string.Empty;
            Sys_ValidationLog validLog = CommonOperate.GetEntity<Sys_ValidationLog>(x => x.UserName == um && x.MD5 == code && !x.IsDeleted, null, out errMsg);
            if (validLog != null)
            {
                validLog.Status = "已使用";
                validLog.ModifyDate = DateTime.Now;
                validLog.ModifyUserName = "admin";
                CommonOperate.OperateRecord<Sys_ValidationLog>(validLog, ModelRecordOperateType.Edit, out errMsg, null, false);
            }
            return Json(null, JsonRequestBehavior.AllowGet);
        }
        #endregion

        #endregion
    }

    /// <summary>
    /// 用户API控制器
    /// </summary>
    public class UserApiController : BaseApiController
    {
        #region 公共方法

        /// <summary>
        /// 获取数据权限组织树
        /// </summary>
        /// <returns></returns>
        [System.Web.Http.HttpGet]
        [System.Web.Http.HttpPost]
        public dynamic GetDataPermissionOrgTree()
        {
            HttpRequestBase request = WebHelper.GetContextRequest(Request);
            JsonResult result = new UserController(request).GetDataPermissionOrgTree() as JsonResult;
            return result.Data;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [System.Web.Http.HttpGet]
        [System.Web.Http.HttpPost]
        public ReturnResult ChangePwd()
        {
            HttpRequestBase request = WebHelper.GetContextRequest(Request);
            JsonResult result = new UserController(request).ChangePwd() as JsonResult;
            return result.Data as ReturnResult;
        }

        /// <summary>
        /// 修改AD域密码
        /// </summary>
        /// <returns></returns>
        [CrossOrigin(OriginHeaderdefault = "*")]
        [System.Web.Http.HttpGet]
        [System.Web.Http.HttpPost]
        public ReturnResult ChangeAdDomainPwd()
        {
            HttpRequestBase request = WebHelper.GetContextRequest(Request);
            string username = MySecurity.Decrypt(request["username"].ObjToStr(), "addomain");
            string oldPwd = MySecurity.Decrypt(request["oldPwd"].ObjToStr(), "addomain");
            string newPwd = MySecurity.Decrypt(request["newPwd"].ObjToStr(), "addomain");
            UserInfo userInfo = UserOperate.GetUserInfoByUn(username);
            if (userInfo == null)
            {
                return new ReturnResult() { Success = false, Message = "用户名不存在" };
            }
            string errMsg = UserOperate.ModifyAdDomainPassword(username, oldPwd, newPwd);
            return new ReturnResult() { Success = string.IsNullOrEmpty(errMsg), Message = errMsg };
        }

        /// <summary>
        /// AD域验证
        /// </summary>
        /// <returns></returns>
        [CrossOrigin(OriginHeaderdefault = "*")]
        [System.Web.Http.HttpGet]
        [System.Web.Http.HttpPost]
        public ReturnResult AdDomainValidate()
        {
            HttpRequestBase request = WebHelper.GetContextRequest(Request);
            string username = MySecurity.Decrypt(request["username"].ObjToStr(), "addomain");
            string pwd = MySecurity.Decrypt(request["pwd"].ObjToStr(), "addomain");
            UserInfo userInfo = UserOperate.GetUserInfoByAdDomain(username, pwd);
            if (userInfo == null)
                return new ReturnResult() { Success = false, Message = "AD域用户不存在" };
            return new ReturnResult() { Success = true, Message = string.Empty };
        }

        #endregion
    }
}
